package com.systop.asset.service.impl;

import com.systop.asset.entity.Asset;
import com.systop.asset.entity.Department;
import com.systop.asset.entity.Transfer;
import com.systop.asset.entity.TransferDetail;
import com.systop.asset.entity.vo.TransferVo;
import com.systop.asset.enums.HttpCodeEnum;
import com.systop.asset.exception.SystemException;
import com.systop.asset.mapper.AssetMapper;
import com.systop.asset.mapper.DepartmentMapper;
import com.systop.asset.mapper.TransferMapper;
import com.systop.asset.service.IDepartmentService;
import com.systop.asset.service.ITransferService;
import com.systop.asset.utils.RandomCodeGenerator;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * <p>ClassName : TransferServiceImpl</p>
 * <p>Description : </p>
 *
 * @author 孙伟光
 * @version 1.0
 * @date 2025/7/2 15:08
 */
@Service
public class TransferServiceImpl implements ITransferService {

    @Autowired
    private TransferMapper transferMapper;

    @Autowired
    private IDepartmentService departmentService;

    @Autowired
    private AssetMapper assetMapper;

    /**
     * 获取调拨单列表，并补充每个调拨单的所属公司名称
     *
     * @param transfer 调拨单查询条件
     * @return 包含公司名称的调拨单VO列表
     */
    @Override
    public List<TransferVo> getTransferList(Transfer transfer) {
        // 1. 根据查询条件获取调拨单基础信息列表
        List<TransferVo> transferVoList = transferMapper.selectTransferVoList(transfer);

        // 2. 遍历列表，为每个调拨单补充所属公司名称
        for (TransferVo transferVo : transferVoList) {
            // 2.1 根据目标部门ID递归查询公司名称
            String companyName = departmentService.getCompanyNameByDeptId(transferVo.getToDeptId(), 0);
            // 2.2 设置公司名称到VO对象
            transferVo.setToCompanyName(companyName);
        }

        // 3. 返回处理后的调拨单列表
        return transferVoList;
    }

    /**
     * 根据调拨单ID获取调拨单详细信息，并补充所属公司名称
     *
     * @param id 调拨单ID
     * @return 包含公司名称的调拨单VO对象，如果不存在则返回null
     */
    @Override
    public TransferVo getTransferById(Long id) {
        // 参数校验：检查资产ID是否为空
        if (id == null) {
            throw new SystemException(HttpCodeEnum.PARAM_NOT_NULL);
        }
        // 1. 根据ID查询调拨单基础信息
        TransferVo transferVo = transferMapper.selectTransferById(id);

        // 2. 如果调拨单存在，则补充公司名称信息
        if (transferVo != null) {
            // 2.1 根据目标部门ID递归查询公司名称
            String companyName = departmentService.getCompanyNameByDeptId(transferVo.getToDeptId(), 0);
            // 2.2 设置公司名称到VO对象
            transferVo.setToCompanyName(companyName);
        }

        // 3. 返回处理后的调拨单对象
        return transferVo;
    }

    /**
     * 添加调拨单及其明细
     * <p>该方法会先添加调拨单主表信息，再批量添加调拨明细信息</p>
     *
     * @param transferVo 调拨单VO对象，包含调拨单基本信息及明细列表
     * @return 调拨单id 如果为null表示添加失败
     * @throws SystemException 当参数为空或插入失败时抛出异常
     */
    @Override
    @Transactional
    public Long addTransferAndDetail(TransferVo transferVo) {
        // 参数校验：调拨单对象不能为空
        if (transferVo == null) {
            throw new SystemException(HttpCodeEnum.PARAM_NOT_NULL);
        }
        // 参数校验：调拨单明细列表不能为空或空列表
        if (transferVo.getTransferDetails() == null || transferVo.getTransferDetails().size() == 0) {
            throw new SystemException(HttpCodeEnum.PARAM_NOT_NULL);
        }
        // 将VO对象转换为实体对象
        Transfer transfer = new Transfer();
        BeanUtils.copyProperties(transferVo, transfer);

        // 设置业务字段：生成调拨单号、操作人信息
        transfer.setOrderNo(RandomCodeGenerator.generateTransferCode());
        transfer.setStatus(0L);
        transfer.setOperatorId((Long) SecurityContextHolder.getContext().getAuthentication().getCredentials());
        transfer.setOperator((String) SecurityContextHolder.getContext().getAuthentication().getPrincipal());

        // 新增调拨单主表记录
        int rows = transferMapper.insertTransfer(transfer);
        if (rows == 0) {
            throw new SystemException(500, "调拨单添加失败");
        }

        // 批量新增调拨明细记录
        for (TransferDetail transferDetail : transferVo.getTransferDetails()) {
            // 设置明细关联的资产ID
            transferDetail.setAssetId(transferDetail.getId());
            // 设置明细关联的调拨单ID
            transferDetail.setTransferId(transfer.getId());
            // 设置明细关联的公司名称
            String companyName = departmentService.getCompanyNameByDeptId(transferVo.getToDeptId(), 0);
            transferDetail.setCompanyName(companyName);
            // 设置明细关联的调拨原因
            transferDetail.setReason(transferVo.getReason());
            // 设置明细关联的快递单号
            transferDetail.setTrackingNumber(transferVo.getTrackingNumber());
            // 添加详情
            int rows1 = transferMapper.insertTransferDetail(transferDetail);
            if (rows1 == 0) {
                throw new SystemException(500, "调拨明细添加失败");
            }
        }
        return transfer.getId();
    }

    /**
     * 审批调拨单
     *
     * @param transfer 调拨单对象，包含审批状态和ID等信息
     * @return 受影响的行数
     * @throws SystemException 当参数为空时抛出异常
     */
    @Override
    @Transactional
    public int approveTransfer(Transfer transfer) {
        // 参数校验：调拨单对象不能为空
        if (transfer == null) {
            throw new SystemException(500, "调拨单对象不能为空");
        }
        // 参数校验：调拨单ID不能为空
        if (transfer.getId() == null) {
            throw new SystemException(500, "调拨单ID不能为空");
        }
        // 参数校验：审批状态不能为空
        if (transfer.getStatus() == null) {
            throw new SystemException(500, "审批状态不能为空");
        }
        // 参数校验：部门ID不能为空
        if (transfer.getToDeptId() == null) {
            throw new SystemException(500, "部门ID不能为空");
        }
        // 参数校验：位置ID不能为空
        if (transfer.getToLocationId() == null) {
            throw new SystemException(500, "位置ID不能为空");
        }
        // 调用Mapper执行审批操作
        int rows = transferMapper.approveTransfer(transfer);
        if (rows == 0){
            throw new SystemException(500, "审批失败");
        }
        // 当调拨单状态为2(审批通过)且更新行数大于0时，处理资产转移
        if (transfer.getStatus() == 2 && rows > 0) {
            // 根据调拨单ID查询所有调拨明细
            List<TransferDetail> transferDetails = transferMapper.selectTransferDetailByTransferId(transfer.getId());

            // 检查调拨明细是否存在且不为空
            if (transferDetails != null && transferDetails.size() > 0) {
                // 遍历每个调拨明细，更新对应资产信息
                for (TransferDetail transferDetail : transferDetails) {
                    // 根据资产ID查询资产信息
                    Asset asset = assetMapper.selectAssetById(transferDetail.getAssetId());
                    // 更新资产所属部门为目标部门ID
                    asset.setDeptId(transfer.getToDeptId());
                    // 更新资产位置为目标位置ID
                    asset.setLocationId(transfer.getToLocationId());
                    // 更新资产负责人为当前登录用户ID
                    asset.setPrincipal((Long) SecurityContextHolder.getContext().getAuthentication().getCredentials());
                    // 保存更新后的资产信息
                    int rows1 = assetMapper.updateAsset(asset);
                    if (rows1 == 0) {
                        throw new SystemException(500, "资产更新失败");
                    }
                }
            }
        }
        return rows;
    }
}
